assert(DongleStub, string.format("clsaver requires DongleStub."))
local clsaver = DongleStub("Dongle-1.0"):New("clsaver")

function clsaver:Initialize()
   self.defaults = {
      profile = {
        zones = {},
        range = 150
      }
   }
end

function clsaver:Enable()
   self.db = self:InitializeDB("clsaver_DB", self.defaults)
   self.version = GetAddOnMetadata("clsaver", "Version")
   self.cmds = self:InitializeSlashCommand("CombatLog Saver - "..self.version, "CLSAVER", "clsaver")
   self.cmds:RegisterSlashHandler("list: Lists zones for which CombatLog is turned on", "^list$", "ListZones")
   self.cmds:RegisterSlashHandler("toggle: Toggles CombatLog on/off for the current zone", "^toggle$", "ToggleTracking")
   self.cmds:RegisterSlashHandler("range: Sets logging range in yards [50-250]", "^range *(%d*)", "SetRange")

   self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "Reconfigure")
   self:RegisterEvent("PLAYER_ENTERING_WORLD", "Reconfigure")
   self:ApplyCustomRange()
end

function clsaver:Disable()
  self:ApplyDefaultRange()
end

function clsaver:IsZoneTracked()
   return self.db.profile.zones[self.current_zone] and true or false
end

function clsaver:ToggleTracking()
   if self.db.profile.zones[self.current_zone] then
      self.db.profile.zones[self.current_zone] = nil
   else
      self.db.profile.zones[self.current_zone] = true
   end
   self:Reconfigure()
   if self.db.profile.zones[self.current_zone] then
      self:Print("CombatLog on for " .. self.current_zone)
   else
      self:Print("CombatLog off for " .. self.current_zone)
   end
end

function clsaver:ListZones()
   if next(self.db.profile.zones) then
      self:Print("CombatLog on in zones:")
      for z,s in pairs(self.db.profile.zones) do
   self:Print("* " .. z)
      end
   else
      self:Print("CombatLog is off for all zones.")
   end
end

local RANGE_VARS = {
   "CombatLogRangeCreature",
   "CombatLogRangeParty",
   "CombatLogRangePartyPet",
   "CombatLogRangeFriendlyPlayers",
   "CombatLogRangeFriendlyPlayersPets",
   "CombatLogRangeHostilePlayers",
   "CombatLogRangeHostilePlayersPets"
}

function clsaver:SetRange(r)
  local range = tonumber(r)
  if not range then
    self:PrintF("Combat log range is set to %d yards.", self.db.profile.range)
  else
    if range >= 50 and range <= 250 then
      self.db.profile.range = range
      self:ApplyCustomRange()
      self:PrintF("Combat log range is set to %d yards.", self.db.profile.range)
    else
      self:PrintF("Invalid range %d. Range must be between 50 and 250 yards.", range)
    end
  end
end

function clsaver:ApplyCustomRange()
  for _,var in ipairs(RANGE_VARS) do
    SetCVar(var, self.db.profile.range)
  end
end

function clsaver:ApplyDefaultRange()
  for _,var in ipairs(RANGE_VARS) do
     SetCVar(var, GetCVarDefault(var))
  end
end

function clsaver:StartLogging()
   assert(not LoggingCombat())
   LoggingCombat(true)
end

function clsaver:StopLogging()
   assert(LoggingCombat())
   LoggingCombat(false)
end

function clsaver:Reconfigure()
   self.current_zone = GetRealZoneText()
   if (self:IsZoneTracked() and not LoggingCombat()) then
      UIErrorsFrame:AddMessage("CombatLog ON", 0.2, 1.0, 0.2, 1.0, UIERRORS_HOLD_TIME)
      self:StartLogging()
   elseif (not self:IsZoneTracked() and LoggingCombat()) then
      UIErrorsFrame:AddMessage("CombatLog OFF", 1.0, 0.0, 0.0, 1.0, UIERRORS_HOLD_TIME)
      self:StopLogging()
   end
end
